package demo;

import de.d3fact.common.events.Event;
import de.d3fact.common.events.IListener;
import de.d3fact.mfslib.processor.Processor;
import de.d3fact.mfslib.sink.Sink;
import de.d3fact.mfslib.source.Source;
import de.d3fact.mfsmodel.TokenTypeConfig;
import de.d3fact.modelapi.Model;
import de.d3fact.modelapi.dataport.IDataport;
import de.d3fact.modelapi.dataport.api.direct.ILongDirectInputport;
import de.d3fact.modelapi.scheduler.Scheduler;

/**
 * !!! Notice for using threads: The components of the model, e. g. the Objects, have to be build in
 * the same thread the nextStep-Method will be called !!! (but you can use global variable to bind
 * these Objects)
 * 
 * @author craymet
 */
public class ThreadDemo extends Thread
{

	private final Scheduler _scheduler = new Scheduler();
	private final Model _model = new Model(_scheduler);

	private final IListener _listener = new IListener()
		{
			@Override
			public void handleEvent(Event e)
			{
				System.out.println("handleEvent");
			}
		};

	/**
	 * 
	 */
	public void run()
	{

		Source source = new Source("Source", this._model);
		Processor machine = new Processor("Processor", this._model);
		Sink sink = new Sink("Sink", this._model);

		machine.getInputChannels()[0].connectTo(source.getOutputChannels()[0]);
		sink.getInputChannels()[0].connectTo(machine.getOutputChannels()[0]);

		source.getOutputChannels()[0].configure(new TokenTypeConfig(0, 1));
		source.<ILongDirectInputport> getPort(Source.DATAPORT_FREQUENCY, IDataport.DIRECTION_INPUT).directValue(100);

		machine.getInputChannels()[0].configure(new TokenTypeConfig(0, 1));
		machine.<ILongDirectInputport> getPort(Processor.DATAPORT_PROCESSING_TIME, IDataport.DIRECTION_INPUT).directValue(200);
		machine.getOutputChannels()[0].configure(new TokenTypeConfig(1, 3));

		sink.getInputChannels()[0].configure(new TokenTypeConfig(1, 1));

		machine.getInputChannels()[0].addListener(this._listener);

		while (this._scheduler.currentTime() < this._scheduler.getEndTime() && this._scheduler.eventCount() > 0)
		{
			try
			{
				// 1 second delay
				Thread.sleep(1000);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			System.out.println("Thread: " + Thread.currentThread().getId());
			this._scheduler.nextStep();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		ThreadDemo _threadTest = new ThreadDemo();
		_threadTest.start();
	}

}
